package com.tgky.ybzb.neo4j.service;

import com.tgky.ybzb.neo4j.entity.NodeEntityObj;
import com.tgky.ybzb.neo4j.entity.PersonWithRelationship;
import com.tgky.ybzb.neo4j.mapper.NodeObjMapper;
import com.tgky.ybzb.utils.ToolUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.core.Neo4jTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Lixx
 * @date 2024/9/4 9:41
 */
@Service
public class NodeObjServiceImpl{

    @Autowired
    private NodeObjMapper nodeObjMapper;

    @Autowired
    private Neo4jTemplate neo4jTemplate;

    /**
     * 保存知识图谱的节点
     * @param map
     * @return
     */
    public List<NodeEntityObj> saveNodeData(Map<String, Object> map) {

        Map<String,NodeEntityObj> nodeMap=new HashMap<>();
        List<Map<String,Object>> nodeList=(List<Map<String,Object>>) map.get("nodes");
        List<NodeEntityObj> list=new ArrayList<>();
        for(Map<String,Object> node:nodeList){
            NodeEntityObj nodeEntityObj=new NodeEntityObj();
            getNode(node,nodeEntityObj);
            nodeMap.put(nodeEntityObj.getId(),nodeEntityObj);
            // 保存节点
            nodeObjMapper.save(nodeEntityObj);
            list.add(nodeEntityObj);
        }
        return list;
    }
    // 给node节点赋值
    public void getNode(Map<String,Object> node, NodeEntityObj nodeEntityObj){
        nodeEntityObj.setId(node.get("id").toString());
        nodeEntityObj.setName(node.get("name").toString());
        nodeEntityObj.setLabel(node.get("label").toString());
        nodeEntityObj.setColor(node.get("color").toString());
        nodeEntityObj.setBackgroundColor(node.get("backgroundColor").toString());
        nodeEntityObj.setShape(node.get("shape").toString());
        nodeEntityObj.setType(node.get("type").toString());
        nodeEntityObj.setSize((List<String>) node.get("size"));
        nodeEntityObj.setX(node.get("x").toString());
        nodeEntityObj.setY(node.get("y").toString());
        // 暂时写死，需要确定类型并每次保存时传入
        nodeEntityObj.setChartType("testChartType");
        nodeEntityObj.setNodeContent(node.get("nodeContent").toString());

    }

    /**
     * 删除节点和数据
     * @param id
     * @return
     */
    public String deleteNodeData(String id) {
       int state=nodeObjMapper.deleteNodeData(id);
       return state==1 ? "操作成功":"操作失败";
    }

    /**
     * 创建两个节点之间的关系
     * @param
     * @return
     */
    public String createEdgeData(NodeEntityObj nodeEntityObj) {

        nodeObjMapper.createEdgeData(nodeEntityObj);
        return "保存成功";
    }
    // 给关系实体类赋值
    public void getEdge(Map<String,Object> edge,NodeEntityObj relationship){
        relationship.setId(edge.get("id").toString());
        relationship.setShape(edge.get("shape").toString());
        relationship.setType(edge.get("type").toString());
        List<Integer> start=new ArrayList<>();
        Map<String,Object> startM=(Map<String,Object>) edge.get("start");
        start.add(Integer.valueOf(startM.get("x").toString()));
        start.add(Integer.valueOf(startM.get("y").toString()));
        relationship.setStart(start);
        List<Integer> end=new ArrayList<>();
        Map<String,Object> endM=(Map<String, Object>) edge.get("end");
        end.add(Integer.valueOf(endM.get("x").toString()));
        end.add(Integer.valueOf(endM.get("y").toString()));
        relationship.setEnd(end);
    }

    /**
     * 删除两个节点之间的关系
     * @param id
     * @return
     */
    public String deleteEdgeData(String id) {
        nodeObjMapper.deleteEdgeData(id);
        return "删除成功";
    }

    /**
     * 获取所有节点信息
     * @return
     */
    public List<NodeEntityObj> getNodeList() {
        return nodeObjMapper.getNodeList();
    }

    /**
     * 根据类型，模糊条件，筛选类型来获取所有的节点或关系
     *
     * @param
     * @param type
     * @param condition
     * @param chartType
     * @return
     */
    public PersonWithRelationship getAllNodeData(String type, String condition, String chartType,String skip) {
        PersonWithRelationship personWithRelationship=new PersonWithRelationship();
        // 如果type是根据节点来查的
        if(StringUtils.isNotBlank(type) && "1".equals(type)){
            String nodeQuery=getQueryAllNode(condition,chartType,skip,"Node");
            List<NodeEntityObj> nodeSet=neo4jTemplate.findAll(nodeQuery,NodeEntityObj.class);
            personWithRelationship.setNode(ToolUtils.fromListToSet(nodeSet));
            // 查询关系
            nodeQuery=getQueryAllNode(condition,chartType,skip,"RelationShip");
            System.out.println(nodeQuery);
            List<NodeEntityObj> relationShipSet=neo4jTemplate.findAll(nodeQuery,NodeEntityObj.class);
            personWithRelationship.setRelationShip(ToolUtils.relationShipListToSet(relationShipSet));
        }

        return personWithRelationship;
    }
    /**
     * 拼接查询条件
     * @param condition
     * @param chartType
     * @param skip
     * @return
     */
    public String getQueryAllNode( String condition, String chartType,String skip,String state){
        StringBuilder stringBuilder=new StringBuilder();
        //拼接节点查询
        stringBuilder.append("match (n:NodeEntityObj)-[r:RELATIONSHIP_TYPE");
        if(StringUtils.isNotBlank(skip)&&"Node".equals(state)){
            stringBuilder.append("*").append(skip);
        }
        stringBuilder.append("]-(m:NodeEntityObj) ");
        stringBuilder.append("where n:NodeEntityObj");
        if(StringUtils.isNotBlank(chartType)){
            stringBuilder.append(" And n.chartType=").append("'").append(chartType).append("'");
        }
        if(StringUtils.isNotBlank(condition)){
            stringBuilder.append(" And n.nodeContent =~ ").append("'.*").append(condition).append(".*' ");
        }
        if("Node".equals(state)){
            stringBuilder.append(" return n");
        }
        else{
            stringBuilder.append(" return n, r.id AS relationShipId,r.sourceId AS sourceId,r.targetId AS targetId");
        }

        return stringBuilder.toString();
    }
    /**
     * 保存导入的知识图谱内容
     * @param map
     * @return
     */
    public String saveimportZstp(Map<String, Object> map) {
        Map<String,NodeEntityObj> nodeMap=new HashMap<>();
        List<Map<String,Object>> nodeList=(List<Map<String,Object>>) map.get("nodes");
        List<Map<String,Object>> edgeList=(List<Map<String,Object>>) map.get("edges");
        for(Map<String,Object> node:nodeList){
            NodeEntityObj nodeEntityObj=new NodeEntityObj();
            getNode(node,nodeEntityObj);
            // 根据名称查出是否存在这个节点存在就只更新内容
            NodeEntityObj nodeExit=nodeObjMapper.getNodeByName(nodeEntityObj);
            if(nodeExit!=null){
                nodeEntityObj.setId(nodeExit.getId());
            }
            nodeMap.put(nodeEntityObj.getId(),nodeEntityObj);
            // 保存节点
            nodeObjMapper.save(nodeEntityObj);
        }
        for(Map<String,Object> edge:edgeList){
            NodeEntityObj relationship=new NodeEntityObj();
            getEdge(edge,relationship);
            NodeEntityObj startNode=nodeMap.get(edge.get("sourceId"));
            NodeEntityObj endNode=nodeMap.get(edge.get("targetId"));
            // 保存关系
            nodeObjMapper.saveEdgeData(startNode,endNode,relationship);
        }
        return "保存成功";
    }

}
